<?php

declare(strict_types=1);
/**
 * This file is part of MineAdmin.
 *
 * @link     https://www.mineadmin.com
 * @document https://doc.mineadmin.com
 * @contact  root@imoi.cn
 * @license  https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
 */
use App\Setting\Service\SettingConfigService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

// 自定义函数库

if (! function_exists('env')) {
    /**
     * 获取环境变量信息.
     */
    function env(string $key, mixed $default = null): mixed
    {
        return \Hyperf\Support\env($key, $default);
    }
}

if (! function_exists('config')) {
    /**
     * 获取配置信息.
     */
    function config(string $key, mixed $default = null): mixed
    {
        return \Hyperf\Config\config($key, $default);
    }
}

if (! function_exists('make')) {
    /**
     * Create an object instance, if the DI container exist in ApplicationContext,
     * then the object will be created by DI container via `make()` method, if not,
     * the object will create by `new` keyword.
     */
    function make(string $name, array $parameters = [])
    {
        return \Hyperf\Support\make($name, $parameters);
    }
}

if (! function_exists('sys_config')) {
    /**
     * 获取后台系统配置.
     *
     * @throws RedisException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function sys_config(string $key, mixed $default = null): mixed
    {
        return container()->get(SettingConfigService::class)->getConfigByKey($key) ?? $default;
    }
}

if (! function_exists('sys_group_config')) {
    /**
     * 获取后台系统配置.
     *
     * @param null|mixed $default
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function sys_group_config(string $groupKey, mixed $default = []): mixed
    {
        return container()->get(SettingConfigService::class)->getConfigByGroupKey($groupKey) ?? $default;
    }
}

if (! function_exists('request')) {
    /**
     * 获取请求
     * @param array|string|null $key
     * @param mixed $default
     * @return mixed
     */
    function request($key = null, $default = null)
    {
        /** @var \Hyperf\HttpServer\Request $request */
        $request = \Hyperf\Context\ApplicationContext::getContainer()->get(\Hyperf\HttpServer\Request::class);
        if (is_null($key)) {
            return $request;
        }

        if (is_array($key)) {
            return $request->inputs($key);
        }

        $value = $request->input($key);

        return is_null($value) ? \Hyperf\Support\value($default) : $value;
    }
}

/**
 * 获取原子锁，用于防止并发
 *
 * 使用示例：
 * ```php
 * $lock = lock('customize_lock_key');
 * if (!$lock->get()) {
 * throw new DefaultException('操作频繁，请稍后再试');
 * }
 * # 业务逻辑代码...
 * $lock->release(); // 释放锁
 * ```
 *
 * @param string $key 原子锁字符串key
 * @param int $seconds 死锁时间（单位秒），需要大于逻辑执行时间。
 * @param string|null $owner
 * @return \App\Utils\RedisLock
 */
function lock(string $key, int $seconds = 60, ?string $owner = null): \App\Utils\RedisLock
{
    return \Hyperf\Support\make(\App\Utils\RedisLock::class, [
        'name' => $key,
        'seconds' => $seconds,
        'owner' => $owner,
    ]);
}

/**
 * 请求场景
 * @return string
 */
function request_scene(): string
{
    if (is_api()) {
        if (request()->is('api/staff/*')) {
            return 'staff';
        }
        if (request()->is('api/admin/*')) {
            return 'admin';
        }
        return 'api';
    }

    return 'default';
}

/**
 * 是否API
 * @return bool
 */
function is_api(): bool
{
    /** @var \Hyperf\HttpServer\Request $request */
    $request = \Hyperf\Context\ApplicationContext::getContainer()->get(\Hyperf\HttpServer\Request::class);
    return $request->is('api/*') || strtolower($request->path()) === 'api';
}

/**
 * @param array|\Hyperf\Collection\Collection $array
 * @param string|int|null $value
 * @param string|int|null $key
 * @return array
 */
function pluck(array|\Hyperf\Collection\Collection $array, string|int|null $value, string|int|null $key = null): array
{
    if ($array instanceof \Hyperf\Collection\Collection) {
        $array = $array->toArray();
    }
    return array_column($array, $value, $key);
}

/**
 * 登录用户数据
 * @param string $scene
 * @param string $key
 * @param mixed|null $default
 * @return mixed
 */
function login_user_data(string $scene = 'default', string $key = '', mixed $default = null): mixed
{
    try {
        $data = user($scene)->getJwt()->getParserData();
    } catch (\Throwable $e) {
        $data = [];
    }
    return \Hyperf\Collection\data_get($data, $key, $default);
}

/**
 * Api用户ID
 * @param string $scene
 * @return int
 */
function api_member_id(string $scene = 'api'): int
{
    return (int)login_user_data($scene, 'id', 0);
}

/**
 * 业务错误日志
 * @param string $name
 * @param \Throwable $e
 * @return void
 */
function business_error_logger(string $name, \Throwable $e): void
{
    logger()->error(sprintf('%s -> %s', $name, $e->getMessage()), $e->getTrace());
}
